#ifndef LOGGING_H_INCLUDED
#define LOGGING_H_INCLUDED

#include "Atomic.h"

namespace CEngine
{

///Defines for various verbosity levels
#define LOG_ERROR   0
#define LOG_WARNING 1
#define LOG_INFO    3
#define LOG_DEBUG   4

///
///A class that will print information to the console and/or to a file.
///
class Logging {
    public:

        ///enumeration for the various systems.
        enum System {
            NONE, MEMORY, SETTINGS, CONTAINERS, FILESYSTEM, STRINGS
        };

        ///Constructor that sets it to only print to console, have a verbosity of 1,
        ///and strings into 80 character lines or what is given.
        Logging(const U8 verbosity = 1, const bool toConsole = true, const bool toFile = false, const U8 charactersPerLine = 80);

        ///Prints a message to the console and/or a file which is broken up into a
        ///set amount of characters per line.
        ///System specifies the system the log came from (controls colour of the message)
        ///Verbosity specifies how verbose the message is, if the class's verbosity is
        ///lower than this the message won't be printed.
        ///The rest is exactly like printf (string can be up to 1023 characters after formatting).
        void
        log(const System system, const U8 verbosity, const char* stringToPrint, ...);

        ///Toggles if messages are sent to the console.
        inline void
        outputToConsole(const bool toggle);

        ///Checks if messages are sent to the console.
        inline bool
        isOutputToConsole(void) const;

        ///Toggles if messages are sent to a file.
        inline void
        outputToFile(const bool toggle);

        ///Checks if messages are sent to the console.
        inline bool
        isOutputToFile(void) const;

        ///Sets the verbosity of the logger.
        inline void
        setVerbosity(const U8 verbosity);

        ///Gets the verbosity of the logger.
        inline U8
        getVerbosity(void) const;

        ///Sets how many characters are in a line.
        inline void
        setCharactersPerLine(const U8 charactersPerLine);

        ///Gets how many characters are in a line.
        inline U8
        getCharactersPerLine(void) const;

        ///Gets the total number of lines printed.
        inline U32
        getTotalLinesPrinted(void) const;

    private:

        ///If the message is sent to the console or not.
        bool toConsole;
        ///If the message is sent to a file or not.
        bool toFile;
        ///Specifies the verbosity of the logger.
        U8 verbosity;

        ///The number of characters per line.
        U8 charactersPerLine;

        ///Total number of lines printed.
        U32 totalLinesPrinted;
};

void
Logging::outputToConsole(const bool toggle) {
    toConsole = toggle;
}

bool
Logging::isOutputToConsole(void) const{
    return toConsole;
}

void
Logging::outputToFile(const bool toggle) {
    toFile = toggle;
}

bool
Logging::isOutputToFile(void) const{
    return toFile;
}

void
Logging::setVerbosity(const U8 v) {
    verbosity = v;
}

U8
Logging::getVerbosity(void) const{
    return verbosity;
}

void
Logging::setCharactersPerLine(const U8 l) {
    charactersPerLine = l;
}

U8
Logging::getCharactersPerLine(void) const{
    return charactersPerLine;
}

U32
Logging::getTotalLinesPrinted(void) const{
    return totalLinesPrinted;
}

}

#endif // LOGGING_H_INCLUDED
